package com.irdstudio.efp.esb.service.impl.zx;

import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.basic.framework.core.util.AESUtility;
import com.irdstudio.basic.framework.core.util.SpringContextUtils;
import com.irdstudio.basic.sequence.service.DefaultPatternDescriptor;
import com.irdstudio.basic.sequence.service.PatternDescriptor;
import com.irdstudio.basic.sequence.service.facade.PatternedLimitableSeqService;
import com.irdstudio.efp.console.service.facade.SCfgParamService;
import com.irdstudio.efp.console.service.vo.SCfgParamVO;
import com.irdstudio.efp.esb.common.client.resp.EsbRespServiceBean;
import com.irdstudio.efp.esb.common.client.resp.EsbRespSysHeadBean;
import com.irdstudio.efp.esb.service.bo.req.BaseNewZXReqBean;
import com.irdstudio.efp.esb.service.bo.req.BaseZXReqBean;
import com.irdstudio.efp.esb.service.bo.req.ZXCXA01QueryReports;
import com.irdstudio.efp.esb.service.bo.req.ZXQueryReports;
import com.irdstudio.efp.esb.service.bo.resp.zx.BaseNewZXResBean;
import com.irdstudio.efp.esb.service.bo.resp.zx.ZXResponseReport;
import com.irdstudio.efp.esb.service.client.ESBClientFactory;
import com.irdstudio.efp.esb.service.client.impl.MSESBBeanCreator;
import com.irdstudio.efp.esb.service.facade.zx.NewZXService;
import com.irdstudio.efp.esb.service.vo.zx.ZXVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.DigestUtils;

import java.nio.charset.Charset;
import java.util.Base64;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;

import static com.irdstudio.basic.sequence.service.DefaultPatternDescriptor.*;
import static java.util.Collections.singletonList;

/**
 * @description:二代征信接口基类
 * @param <Q> 请求查询的报文类型
 * @param <P> 接口返回的结果类型
 * @date:2020年01月22日
 * @author:dengqiwen
 */
public abstract class BaseNewZXService<Q extends ZXQueryReports, P extends ZXResponseReport> implements NewZXService<Q> {



	private static Logger log = LoggerFactory.getLogger(BaseNewZXService.class);


	public ZXVO Zxservice(Q queryReports,List<SCfgParamVO> params) throws Exception {
		log.info("处理二代征信接口开始， 请求参数：" + queryReports);
		String IntfAcsAutUsrAcctNo= null,str = null;
		for (SCfgParamVO param : params) {
			if(param.getParamKey().equals("ZX_IntfAcsAutUsrAcctNo")){
				IntfAcsAutUsrAcctNo=param.getParamValue();
				continue;
			}
			if(param.getParamKey().equals("ZX_IntfAcsAutUsrPswd")){
				str=param.getParamValue();
				continue;
			}
		}
		ZXCXA01QueryReports zx=(ZXCXA01QueryReports)queryReports;

		//解密，解密也是有这个key,如果解密的key换了，加密的key也要换，加密的方法也在统一类里面
		String IntfAcsAutUsrPswd= AESUtility.decryptMD5Key(str,"y3PsTEpHRnI9EZe0zBNeaIzi1225MEhGIJcaPzSBsKI=");
		BaseNewZXReqBean<Q> reqBean=new BaseNewZXReqBean.Builder<Q>()
				.withTxnCd("ZXCXA01")
				.withRqstSysCd("WANGDAI")
				.withIntfAcsAutUsrAcctNo(IntfAcsAutUsrAcctNo)
				.withIntfAcsAutUsrPswd(IntfAcsAutUsrPswd)
				.withLPBrchID("a5adabc8ae00417bbe1b4f54423f4d03")
				.withQryAppTp(zx.getQryAppTp()).withRprtUsr(zx.getRprtUsr()).withRprtUsrBlngDept(zx.getRprtUsrBlngDept())
				.withCustNm(zx.getCustNm()).withIdentTp(zx.getIdentTp()).withIdentNo(zx.getIdentNo()).withQryRsn(zx.getQryRsn()).withQryTp(zx.getQryTp())
				.withAcqrngCustSrc(zx.getAcqrngCustSrc()).withPdNm(zx.getPdNm()).withAuthMd(zx.getAuthMd())
				.withCrdtRprtQryMd(zx.getCrdtRprtQryMd())
				.withAuthTm(zx.getAuthTm()).withAuthStrtDt(zx.getAuthStrtDt()).withAuthStopDt(zx.getAuthStopDt())
				.withLisSrcURL("66").withAuthArchvsSrcURL("66")//这两个值暂时随便填
                .withQryVer("01")
				.build();

		//preProcess(reqBean);

		try {
			EsbRespServiceBean esbRespServiceBean = ESBClientFactory.buildClient()
					.withBody(reqBean)
					.withTradeNo(tradeNo())
					.withScene(scene())
					.withESBBeanFactory((MSESBBeanCreator) SpringContextUtils.getBean("MSESBBeanCreator"))
					.create()
					.sendAndReceive();
			EsbRespSysHeadBean esbRespSysHeadBean = esbRespServiceBean.getSysHead();
			BaseNewZXResBean<P> resBean = esbRespServiceBean.getBody(converter());
			if (!Objects.equals(esbRespSysHeadBean.getRetSt(), "S")) {
                StringBuilder errMsg = new StringBuilder("二代征信接口异常");
				errMsg.append(",错误信息: ").append(esbRespSysHeadBean.getRetInfArry().get(0).getRetMsg());
                throw new ESBException(errMsg.toString());
            }
			if (Objects.equals(esbRespSysHeadBean.getRetSt(), "S") && resBean.getRprtQrySt().equals("7")) {
				ZXVO zxvo = new ZXVO(Boolean.TRUE,"");
				return  zxvo;
			}
			String bodyJson=esbRespServiceBean.getBodyJson();
			//去掉html格式的征信报告字段，html另外存
            String html=bodyJson.substring(bodyJson.indexOf("\"HTMLFmtCrRfrncRprt\""));
            String substring = html.substring(0, html.indexOf(",")+1);
            String jsonInfo = bodyJson.replace(substring, "");
            resBean.setJSONFmtCrRfrncRprt(jsonInfo);
			return postProcess(reqBean, resBean);
		} catch (ESBException e) {
			log.error(e.getMessage());
			throw e;
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new ESBException(e);
		}


	}

	/* 对queryReports进行预处理（可选),由子类实现  */
	protected void preProcess(BaseNewZXReqBean<Q> reqBean) { };
	/* 对接口返回结果进行处理，并返回包装后的结果 */
	protected abstract ZXVO postProcess(BaseNewZXReqBean<Q> reqBean, BaseNewZXResBean<P> resBean) throws Exception;
	/* 各接口的交易码 */
	protected abstract String tradeNo();
	/* 各接口的服务场景 */
	protected abstract String scene();
	/* 各接口实现需提供将 返回JSON 转换为 Bean 的转换策略 */
	protected abstract Function<String , BaseNewZXResBean<P>> converter() ;




}
